/**
 *	@file	bong_case.c
 *	@brief	ボングリケースシステム(非常駐)
 *	@author	Miyuki Iwasawa
 *	@date	08.08.04
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "itemtool/myitem.h"
#include "gflib/touchpanel.h"
#include "msgdata/msg.naix"

#include "savedata/config.h"
#include "savedata/mail.h"
#include "poketool/pokeparty.h"
#include "poketool/calc_humor.h"
#include "application/pokelist.h"
#include "application/bong_case.h"
#include "bc_sys.h"
#include "bc_app.h"

#include "system/pm_overlay.h"

extern PROC_RESULT BongUseDemoProc_Init(PROC* proc,int* seq);
extern PROC_RESULT BongUseDemoProc_Main(PROC* proc,int* seq);
extern PROC_RESULT BongUseDemoProc_End(PROC* proc,int* seq);

//=========================================================
//データ型定義
//=========================================================
//システムシーケンス定義
enum{
 SSEQ_INIT,
 SSEQ_APPCALL,
 SSEQ_APPWAIT,
 SSEQ_PLISTCALL,
 SSEQ_PLISTWAIT,
 SSEQ_USECALL,
 SSEQ_USEWAIT,
 SSEQ_EXIT,
};

//=========================================================
//プロトタイプ
//=========================================================
static BOOL BongCaseSysProcCall(PROC** proc);
static void sys_InitData(BC_SYSWORK* wk);
static void sys_EndData(BC_SYSWORK* wk);


static int seq_AppCall(BC_SYSWORK* wk);
static int seq_AppWait(BC_SYSWORK* wk);
static int seq_PokeListCall(BC_SYSWORK* wk);
static int seq_PokeListWait(BC_SYSWORK* wk);
static int seq_UseDemoCall(BC_SYSWORK* wk);
static int seq_UseDemoWait(BC_SYSWORK* wk);

static void sub_ViewClear(void);

//=========================================================
//コードエリア
//=========================================================
/**
 *	@brief	サブプロセス呼び出し処理
 */
static BOOL BongCaseSysProcCall(PROC** proc)
{
	if(*proc){
		if(ProcMain(*proc)){
			PROC_Delete(*proc);
			*proc = NULL;
			return TRUE;
		}
	}
	return FALSE;
}

//=========================================================
//プロセス定義
//=========================================================
/**
 *	@brief	ボングリケースモジュール呼び出し
 */
PROC_RESULT BongCaseSysProc_Init(PROC* proc,int* seq)
{
	BC_SYSWORK* wk = NULL;

	sub_ViewClear();

	//ヒープ作成
	HeapStatePush();
	sys_CreateHeap(HEAPID_BASE_APP,HEAPID_BONGCASE_SYS,0x2000);

	wk = PROC_AllocWork(proc,sizeof(BC_SYSWORK),HEAPID_BONGCASE_SYS);
	MI_CpuClear8(wk,sizeof(BC_SYSWORK));

	wk->heapID = HEAPID_BONGCASE_SYS;
	wk->param = (BONGCASE_PARAM*)PROC_GetParentWork(proc);

	//引継ぎデータ初期化
	sys_InitData(wk);

	return PROC_RES_FINISH;
}

/**
 *	@brief	ボングリケースモジュールメイン
 */
PROC_RESULT BongCaseSysProc_Main(PROC* proc,int* seq)
{
	BC_SYSWORK* wk = (BC_SYSWORK*)PROC_GetWork(proc);

	switch(*seq){
	case SSEQ_INIT:
		if(wk->param->call_mode == BONGCASE_SHOP){
			*seq = SSEQ_PLISTCALL;
		}else{
			*seq = SSEQ_APPCALL;
		}
		break;
	case SSEQ_APPCALL:
		*seq = seq_AppCall(wk);
		break;
	case SSEQ_APPWAIT:
		*seq = seq_AppWait(wk);
		break;
	case SSEQ_PLISTCALL:
		*seq = seq_PokeListCall(wk);
		break;
	case SSEQ_PLISTWAIT:
		*seq = seq_PokeListWait(wk);
		break;
	case SSEQ_USECALL:
		*seq = seq_UseDemoCall(wk);
		break;
	case SSEQ_USEWAIT:
		*seq = seq_UseDemoWait(wk);
		break;
	case SSEQ_EXIT:
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	ボングリケースモジュール終了
 */
PROC_RESULT BongCaseSysProc_End(PROC* proc,int* seq)
{
	BC_SYSWORK* wk = (BC_SYSWORK*)PROC_GetWork(proc);

	sub_ViewClear();

	//引継ぎデータ書き戻し
	sys_EndData(wk);

	//ワーク解放
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(HEAPID_BONGCASE_SYS);

	sys_DeleteHeap(HEAPID_BONGCASE_SYS);

	return PROC_RES_FINISH;
}

/**
 *	@brief	ぼんぐりジュースをポケモンに与える
 */
void BongSys_JuicePara2Poke(BONG_JUICE* juice,POKEPARTY* party,u8 pos)
{
	int i;
	s8	param[PM_PERFORMANCE_MAX];
	u8	sub = 0,mild = 0;
	u8	m_flavor,s_flavor;
	PM_CONDITION pc;
	BONGJUICE_FLAVOR flavor;

	MI_CpuClear8(param,sizeof(u8)*PM_PERFORMANCE_MAX);

	//ジュースの味値取得
	BongJuice_GetFlavorParam(juice,&flavor);
	mild = juice->mild;
	if(flavor.main.flavor >= BONG_FLAVOR_MIX){
		m_flavor = flavor.order[0];
	}else{
		m_flavor = flavor.main.flavor;
	}
	if(flavor.sub.flavor >= BONG_FLAVOR_MIX){
		s_flavor = flavor.order[1];
	}else{
		s_flavor = flavor.sub.flavor;
	}

	//現在の調子値取得
	PokeParty_GetPokeCondition(party,&pc,pos);

	param[m_flavor] = (u8)((float)flavor.main.level * 1.5f);
	if(flavor.main.level > 0){
		param[m_flavor] += 10;	//メインボーナス
	}
	param[s_flavor] = (u8)((float)flavor.sub.level * 1.5f);
	sub = flavor.main.level + flavor.sub.level;

	if(mild == 255){
		sub = (u8)((float)sub * 0.1f);
	}else if(mild >= 200){
		sub = (u8)((float)sub * 0.2f);
	}else{
		u8 val = mild/25;
		sub = (u8)((float)sub * (1.0f - (((float)val)*0.1f)));
	}
	//一番低い値を持つ味からマイナス
	param[flavor.order[BONG_FTYPE_MAX-1]] -= sub;

	OS_Printf("PMコンディションセット\n");
	for(i = 0;i < PM_PERFORMANCE_MAX;i++){
		s16	tmp = (s16)param[i];
		if(tmp < -127){
			tmp = -127;
		}else if(tmp > 127){
			tmp = 127;
		}
		OS_Printf("->param%d src = %d set = %d\n",
			i,pc.condition[i],tmp);
		pc.condition[i] = (s8)tmp;
	}
	PokeParty_SetPokeCondition(party,&pc,pos);

	//機嫌値Add
	CalcHumor_Calc(PokeParty_GetMemberPointer(party,pos), HUMOR_BONJUICE);
}

///////////////////////////////////////////////////////////////////////////////
//サブ

/**
 *	@brief	引継ぎデータ初期化
 */
static void sys_InitData(BC_SYSWORK* wk)
{
	if(wk->param->ret_wk != NULL){
		*wk->param->ret_wk = FALSE;
	}
	switch(wk->param->call_mode){
	case BONGCASE_NORMAL:
		wk->mode = SYSMODE_NORMAL;
		break;
	case BONGCASE_POT:
		wk->mode = SYSMODE_POT;
		break;
	case BONGCASE_BALL:
		wk->mode = SYSMODE_BALL;
		break;
	case BONGCASE_SHOP:
		wk->use_type = USETYPE_SHOP;
		wk->mode = SYSMODE_NORMAL;	//ケースを呼ばないので使わないが一応初期化
		wk->juice_id = wk->param->juice_id;
		return;
	}
	wk->use_type = USETYPE_ITEM;
	wk->juice_id = BONG_JUICE_MINE;
}

/**
 *	@brief	引継ぎデータ終了処理
 */
static void sys_EndData(BC_SYSWORK* wk)
{
	//キーモード書き戻し
//	KeyTouchStatus_SetTouchOrKey(wk->sp->param->kt_status,wk->key_mode);
}

/**
 *	@brief	ぼんぐりケースアプリコール
 */
static int seq_AppCall(BC_SYSWORK* wk)
{
	// オーバーレイID宣言
	FS_EXTERN_OVERLAY(bong_case);

	static const PROC_DATA BongCaseProcData = {
		BongCaseProc_Init,
		BongCaseProc_Main,
		BongCaseProc_End,
		FS_OVERLAY_ID(bong_case),
	};

	wk->proc = PROC_Create(&BongCaseProcData,wk,wk->heapID);

	return SSEQ_APPWAIT;
}

/**
 *	@brief	ぼんぐりケースアプリ待ち
 */
static int seq_AppWait(BC_SYSWORK* wk)
{
	if(!BongCaseSysProcCall(&wk->proc)){
		return SSEQ_APPWAIT;
	}
	if(wk->mode == SYSMODE_PLIST){
		wk->ret_poke = 0;
		return SSEQ_PLISTCALL;
	}
	return SSEQ_EXIT;
}

/**
 *	@brief	ポケモンリストアプリコール
 */
static int seq_PokeListCall(BC_SYSWORK* wk)
{
	PLIST_DATA* pld;

	//ポケモンリスト呼び出し
	pld = sys_AllocMemory( wk->heapID, sizeof(PLIST_DATA) );
	MI_CpuClear8( pld,sizeof(PLIST_DATA) );
	pld->pp =SaveData_GetTemotiPokemon(wk->param->save);
	pld->myitem = SaveData_GetMyItem(wk->param->save);
	pld->type = PL_TYPE_SINGLE;
	pld->mode = PL_MODE_PORUTO;
	pld->cfg = SaveData_GetConfig(wk->param->save);
	pld->mailblock = SaveData_GetMailBlock( wk->param->save );
	pld->fsys = NULL;
	pld->kt_status = wk->param->kt_status;
	pld->ret_sel = wk->ret_poke;

	wk->proc = PROC_Create(&PokeListProcData,pld,wk->heapID);
	wk->app_wk = (void*)pld;
	return SSEQ_PLISTWAIT;
}

/**
 *	@brief	ポケモンリストアプリ終了待ち
 */
static int seq_PokeListWait(BC_SYSWORK* wk)
{
	u8	pos;
	PLIST_DATA *pld;
	BONGURI_SAVE* bong_sv;
	if(!BongCaseSysProcCall(&wk->proc)){
		return SSEQ_PLISTWAIT;
	}

	//戻り値チェック
	pld = (PLIST_DATA*)wk->app_wk;
	pos = pld->ret_sel;
	wk->ret_poke = pos;	///手持ちナンバー保存
	sys_FreeMemoryEz(wk->app_wk);
	wk->app_wk = NULL;


	if(pos == PL_SEL_POS_EXIT){
		if(wk->param->call_mode == BONGCASE_SHOP){
			return SSEQ_EXIT;
		}
		return SSEQ_APPCALL;	//ケースに戻る
	}
	return SSEQ_USECALL;
}

/**
 *	@brief	ジュース使用アプリコール
 */
static int seq_UseDemoCall(BC_SYSWORK* wk)
{
	// オーバーレイID宣言
	FS_EXTERN_OVERLAY(bong_case);

	static const PROC_DATA BongUseProcData = {
		BongUseDemoProc_Init,
		BongUseDemoProc_Main,
		BongUseDemoProc_End,
		FS_OVERLAY_ID(bong_case),
	};

	wk->proc = PROC_Create(&BongUseProcData,wk,wk->heapID);

	return SSEQ_USEWAIT;
}

/**
 *	@brief	ジュース使用アプリ待ち
 */
static int seq_UseDemoWait(BC_SYSWORK* wk)
{
	if(!BongCaseSysProcCall(&wk->proc)){
		return SSEQ_USEWAIT;
	}
	if(wk->mode == SYSMODE_PLIST){
		return SSEQ_PLISTCALL;
	}
	if(wk->param->call_mode == BONGCASE_SHOP){
		return SSEQ_EXIT;
	}
	return SSEQ_APPCALL;
}

/**
 *	@brief	画面初期化
 */
static void sub_ViewClear(void)
{
	sys_VBlankFuncChange(NULL, NULL);
	sys_HBlankIntrStop();	//HBlank割り込み停止

	GF_Disp_GX_VisibleControlInit();
	GF_Disp_GXS_VisibleControlInit();
	GX_SetVisiblePlane(0);
	GXS_SetVisiblePlane(0);

	WIPE_SetBrightness(WIPE_DISP_MAIN,WIPE_FADE_BLACK);
	WIPE_SetBrightness(WIPE_DISP_SUB,WIPE_FADE_BLACK);
	WIPE_ResetWndMask(WIPE_DISP_MAIN);
	WIPE_ResetWndMask(WIPE_DISP_SUB);
}
